package com.yunji.framework_template.web.controller;

import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URI;
import java.util.List;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.yunji.framework_template.biz.cache.CacheService;
import com.yunji.framework_template.biz.service.SitesInfoService;
import com.yunji.framework_template.common.http.HttpConnection;
import com.yunji.framework_template.common.http.WebIconFinder;
import com.yunji.framework_template.common.util.FileUtil;
import com.yunji.framework_template.common.util.ImageUtil;
import com.yunji.framework_template.common.util.StringUtil;
import com.yunji.framework_template.common.web.Page;
import com.yunji.framework_template.common.web.Result;
import com.yunji.framework_template.orm.datasource.HandleDataSource;
import com.yunji.framework_template.orm.persistence.model.SitesInfo;
import com.yunji.framework_template.orm.persistence.model.SitesType;
import lombok.extern.slf4j.Slf4j;

/**
 * Created by fenglibin on 2018/11/15.
 */
@Slf4j
@Controller
@RequestMapping("/sitesInfo/")
public class SitesInfoController {

    @Value("#{settings['system.domain']}")
    private String           systemDomain;
    @Value("#{settings['excludeFromAllCountries']}")
    private String           excludeFromAllCountries;

    @Autowired
    private SitesInfoService sitesInfoService;

    @Autowired
    private CacheService     cacheService;

    @RequestMapping("selectAll")
    @ResponseBody
    public Result<List<SitesInfo>> selectAll() {
        return Result.success(sitesInfoService.selectAll());
    }

    @RequestMapping("select")
    @ResponseBody
    public Result<SitesInfo> selectByPrimaryKey(Integer id) {
        return Result.success(sitesInfoService.selectByPrimaryKey(id));
    }

    @RequestMapping("selectByCondition")
    @ResponseBody
    public Result<List<SitesInfo>> selectByCondition(SitesInfo record) {
        return Result.success(sitesInfoService.selectByCondition(record));
    }

    @RequestMapping("count")
    @ResponseBody
    public Result<Integer> count(SitesInfo record) {
        return Result.success(sitesInfoService.count(record));
    }

    @RequestMapping("insert")
    @ResponseBody
    public Result<Integer> insertSelective(SitesInfo record) {
        return Result.success(sitesInfoService.insertSelective(record));
    }

    @RequestMapping("update")
    @ResponseBody
    public Result<Integer> updateByPrimaryKeySelective(SitesInfo record) {
        return Result.success(sitesInfoService.updateByPrimaryKeySelective(record));
    }

    @RequestMapping("selectByPage")
    @ResponseBody
    public Result<Page<List<SitesInfo>>> selectByPage(Page<SitesInfo> page) {
        List<SitesInfo> list = null;
        page = page.sequentialDisplayCalculate(sitesInfoService.count(page.getObj()));
        if (page.getTotalCount() > 0) {
            list = sitesInfoService.selectByPage(page);
        }
        Page<List<SitesInfo>> result = new Page<List<SitesInfo>>(page, list);
        return Result.success(result);
    }

    @RequestMapping("deleteByCondition1")
    @ResponseBody
    public Result<Integer> deleteByCondition(SitesInfo record) {
        return Result.success(sitesInfoService.deleteByCondition(record));
    }

    @RequestMapping("delete1")
    @ResponseBody
    public Result<Integer> deleteByPrimaryKey(Integer id) {
        return Result.success(sitesInfoService.deleteByPrimaryKey(id));
    }

    @RequestMapping(value = "/more/{typeCode}", method = { RequestMethod.GET })
    @ResponseBody
    public ModelAndView more(@PathVariable("typeCode") String typeCode) {
        ModelAndView view = new ModelAndView("home/type_site");
        view.getModelMap().put("typeCode", typeCode);
        SitesType sitesType = cacheService.getCache().getSitesTypeCodeAsKey().get(typeCode);
        if (sitesType == null) {
            return view;
        }
        List<SitesInfo> sitesInfoList = cacheService.getCache().getSubTypeSites().get(typeCode);
        view.getModelMap().put("sitesInfoList", sitesInfoList);
        view.getModelMap().addAttribute("IndexType", "HiIndia");
        view.getModelMap().addAttribute("systemDomain", systemDomain);
        return view;
    }

    /**
     * 根据用户输入的域名，获取本地的图片
     * 
     * @param request
     * @param response
     * @throws Exception
     */
    @RequestMapping(value = "/favicon", method = { RequestMethod.GET })
    public void getFacicon(HttpServletRequest request, HttpServletResponse response) throws Exception {
        response.setContentType("image/png");
        String domain = request.getParameter("domain");
        if (StringUtil.isEmpty(domain)) {
            return;
        }
        String host = null;
        if (domain.startsWith("http")) {
            URI uri = new URI(domain);
            host = uri.getHost().toLowerCase();
        } else {
            host = domain;
        }

        byte[] bytes = null;

        ByteArrayOutputStream out = new ByteArrayOutputStream();
        BufferedImage bufferedImage = cacheService.getCountryCache().getIcons().get(host);
        if (bufferedImage != null) {
            ImageIO.write(bufferedImage, "png", out);
            bytes = out.toByteArray();
        } else {
            // 获取远程文件的字节数组
            bytes = HttpConnection.readRemoteFileToBytes("https://www.google.com/s2/favicons?domain=" + host);
            if (bytes != null) {
                // 将其加入到缓存中
                cacheService.getCountryCache().getIcons().put(host, ImageUtil.getBufferedImageFomBytes(bytes));
                // 将其写出到文件中
                FileUtil.writeByteToFile(bytes, cacheService.getSitePath() + "/images/icons/" + host + ".ico");
            } else {
                response.setStatus(302);
                response.setHeader("Location", "https://www.google.com/s2/favicons?domain=" + host);
                response.sendRedirect("https://www.google.com/s2/favicons?domain=" + host);
            }
        }
        if (bytes != null) {
            response.getOutputStream().write(bytes);
            response.getOutputStream().flush();
            response.getOutputStream().close();
        }

    }

    @RequestMapping(value = "/crawleSiteIcon", method = { RequestMethod.GET })
    @ResponseBody
    public String crawleSiteIcon(HttpServletRequest request, HttpServletResponse response) throws IOException {
        String[] countryArr = cacheService.getCountries().split(",");
        for (String countryCode : countryArr) {
            if (excludeFromAllCountries.indexOf(countryCode) >= 0) {
                continue;
            }
            log.info("Current crawle site icon from country code:" + countryCode);
            HandleDataSource.putDataSource(countryCode);
            List<SitesInfo> sitesInfoList = sitesInfoService.selectAll();
            for (SitesInfo sitesInfo : sitesInfoList) {
                String url = sitesInfo.getUrl();
                String icon = sitesInfo.getIco();
                if (icon != null && icon.length() > 0) {
                    continue;
                }
                icon = WebIconFinder.getIconUrlString(url);
                log.info("Get icon from "+url + ", icon is:" + icon);
                if (icon != null && icon.length() > 20) {
                    sitesInfo.setIco(icon);
                    sitesInfoService.updateByPrimaryKey(sitesInfo);
                }
            }
        }
        return "OK";
    }

}
